import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:cher_flare/config/config.dart';
import 'package:cher_flare/config/url_api.dart';
import 'package:cher_flare/http/http_utils.dart';
import 'package:cher_flare/modules/login/models/ly_login_info_manager.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/cupertino.dart';

import '../http/http_config.dart';

/// 打点请求头key统一传参
class LYLogHeadersKey {
  static const String lyData = "data";
  static const String lyLogType = "log_type";
  static const String lySubtype = "subtype";
  static const String lyBehavior = "behavior";
  static const String lyDeviceId = "device-id";
  static const String lyAndroidId = "android_id";
  static const String lyUserId = "user_id";
  static const String lyPkg = "pkg";
  static const String lyChnId = "chn_id";
  static const String lyVer = "ver";
  static const String lyPlatform = "platform";
  static const String lyModel = "model";
  static const String lyPVer = "p_ver";
  static const String lyLanId = "lan_id";
  static const String lySecId = "sec_id";
  static const String lyUtmSource = "utm_source";
  static const String lyAfAdgroupId = "af_adgroup_id";
  static const String lyAfAdset = "af_adset";
  static const String lyAfAdsetId = "af_adset_id";
  static const String lyAfStatus = "af_status";
  static const String lyAfAgency = "af_agency";
  static const String lyAfChannel = "af_channel";
  static const String lyAfCampaign = "campaign";
  static const String lyAfCampaignId = "campaign_id";
  static const String lyCountry = "country";
  static const String lysysLan = "sys_lan";
}

/// 打点中所有涉及到的页面KEY
class LYLogPages {
  static const String launch = "launch";
  static const String quickLogin = "quicklogin";
  static const String appleLogin = "applelogin";
  static const String terms = "terms";
  static const String privacy = "privacy";
  static const String loginSuccess = "loginsuccess";
  static const String purchase = "purchase";
  static const String createOrder = "createorder";
  static const String editAvatar = "editavatar";
  static const String logout = "logout";
  static const String deleteAccount = "deleteaccount";
  static const String customer = "customer";
  static const String report = "report";
  static const String block = "block";

  static const String tab1 = "tab1";
  static const String tab2 = "tab2";
  static const String tab3 = "tab3";
  static const String tab4 = "tab4";

//key值（字符串）参考下面的埋点事件
  /*
  1. 启动页面埋点，page -- ’launch‘
2. 登录页面埋点
  1. 快速登录，page -- 'quicklogin'
  2. 苹果登录，page -- 'applelogin'
  3. 用户协议，page -- 'terms'
  4. 隐私协议，page -- 'privacy'
  5. 登录成功 ，page -- 'loginsuccess'
3. 各主tab点击事件埋点
4. 内购埋点
  1. 打开充值页面，page -- 'purchase'
  2. 创建内购订单，page -- 'createorder'
5. 我的埋点
  1. 编辑头像，page -- 'editavatar'
  2. 退出登录，page -- 'logout'
  3. 删除账号，page -- 'deleteaccount'
  4. 点击客服，page -- 'customer'
6. 其它
  1. 举报，page -- 'report'
  2. 拉黑，page -- 'block'
  * */
}

class LYUseLogManager {
  LYUseLogManager._();

  static const String _event = 'event';
  static const String _tm = 'tm';
  static const String _page = 'page';
  static const String _subPage = 'subPage';
  static const String _terPage = 'terPage';
  static const String _broadcasterId = 'broadcasterId';
  static const String _duration = 'duration';

  static void stat({
    String? page,
    String? subPage,
    String? terPage,
    String? broadcasterId,
  }) {
    var map = <String, dynamic>{};
    // ⚠️page传入下方的埋点事件page值
    if (page != null) {
      map[_page] = page;
    }
    if (subPage != null) {
      map[_subPage] = subPage;
    }
    if (terPage != null) {
      map[_terPage] = terPage;
    }
    if (broadcasterId != null) {
      map[_broadcasterId] = broadcasterId;
    }
    map[_duration] = 0;
    map[_event] = 'pv';
    map[_tm] = DateTime.now().millisecondsSinceEpoch;

    debugPrint('$map');
    LYLogManger().putLog(LYLogType.globalBehavior, map);
  }
}

/// 打点类型
enum LYLogType {
  globalBehavior('event', 'global_behavior', 'event'),
  clickEvent("event", "click", "event");

  final String logType;
  final String subType;
  final String behavior;

  const LYLogType(this.logType, this.subType, this.behavior);
}

// 打点管理
class LYLogManger {
  static final LYLogManger _instance = LYLogManger._internal();
  factory LYLogManger() {
    return _instance;
  }
  LYLogManger._internal();

  static const String tag = "LogManger"; // 日志标签
  static const int limitSize = 20; // 打点任务最多缓存长度
  static int _serialId = 0;
  // 每次启动App该值会修改
  final String launcherId =
      generateMD5('${DateTime.now().millisecondsSinceEpoch}${Config.deviceId}');
  final List<Map<String, dynamic>> cacheList = [];
  bool _isWaitingForSend = false; // 是否需要延迟上报

  /// 上报日志
  void putLog(LYLogType logType, Map<String, dynamic>? event) {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    cacheList.insert(0, itemData);
    sendDelayed();
  }

  /// 延时发送日志
  void sendDelayed() {
    if (_isWaitingForSend) {
      return;
    }
    _isWaitingForSend = true;
    Timer(const Duration(milliseconds: 2000), () {
      _isWaitingForSend = false;
      sendLog(false);
    });
  }

  /// 发日志打点
  void sendLog(bool forceUploadAll) {
    try {
      List<Map<String, dynamic>> sendList = [];
      if (cacheList.isEmpty) {
        return;
      } else if (cacheList.length >= limitSize && !forceUploadAll) {
        sendList.addAll(cacheList.sublist(0, limitSize));
        cacheList.removeRange(0, limitSize);
      } else {
        sendList.addAll(cacheList);
        cacheList.clear();
      }
      _uploadUseLog(sendList, true);
    } catch (e) {
      debugPrint('$e');
    }
  }

  /// 立马发送日志
  void putLogRightNow(LYLogType logType, Map<String, dynamic>? event) {
    if (logType.logType.isEmpty ||
        logType.subType.isEmpty ||
        logType.behavior.isEmpty ||
        event == null ||
        event.isEmpty) {
      return;
    }
    Map<String, dynamic> itemData = _buildItemData(
        logType.logType, logType.subType, logType.behavior, event);
    List<Map<String, dynamic>> list = [];
    list.add(itemData);

    _uploadUseLog(list, false);
  }

  /// 执行上传
  Future<void> _uploadUseLog(
      List<Map<String, dynamic>> sendList, bool isContinue) async {
    final response = await HttpUtils.getInstance
        .post(HttpConfig.logBaseUrl + URLApi.logLiveChat, data: sendList);
    if (response.isSuccess && isContinue) {
      sendDelayed();
    }
  }

  Map<String, dynamic> _buildItemData(String logType, String subType,
      String behavior, Map<String, dynamic>? event) {
    Map<String, dynamic> itemData = {};
    itemData[LYLogHeadersKey.lyData] = [event];
    itemData[LYLogHeadersKey.lyLogType] = 'event';
    itemData[LYLogHeadersKey.lySubtype] = 'global_behavior';
    itemData[LYLogHeadersKey.lyBehavior] = 'event';
    itemData[LYLogHeadersKey.lyDeviceId] = Config.deviceId;
    itemData[LYLogHeadersKey.lyUserId] =
        LYLoginInfoManager.getInstance.loginModel?.userInfo?.userId;
    itemData[LYLogHeadersKey.lyPkg] = Config.packageName;
    itemData[LYLogHeadersKey.lyChnId] = '';
    itemData[LYLogHeadersKey.lyVer] = Config.version;
    itemData[LYLogHeadersKey.lyPlatform] =
        Platform.isAndroid ? 'Android' : 'iOS';
    itemData[LYLogHeadersKey.lyModel] = Config.deviceModel;
    itemData[LYLogHeadersKey.lyPVer] = Config.buildNumber;
    itemData[LYLogHeadersKey.lyLanId] = launcherId;
    itemData[LYLogHeadersKey.lySecId] = _serialId++;
    itemData[LYLogHeadersKey.lysysLan] = Config.lanCode;
    itemData[LYLogHeadersKey.lyCountry] =
        LYLoginInfoManager.getInstance.loginModel?.userInfo?.country;
    ;
    itemData["tm"] = DateTime.now().millisecondsSinceEpoch;
    return itemData;
  }

  static String generateMD5(String data) {
    var content = const Utf8Encoder().convert(data);
    var digest = md5.convert(content);
    return digest.toString();
  }
}
